﻿using System.Text;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Diagnostics;
using System.Windows;
using System;

namespace StudentInfoSystem.Core.Utils;

public static class JsonData
{
    private static readonly JsonSerializerOptions _jsonOptions = new()
    {
        ReferenceHandler = ReferenceHandler.IgnoreCycles, // 忽略循环引用
        WriteIndented = true,
        IgnoreReadOnlyProperties = true,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        Converters = { new JsonStringEnumConverter() }
    };

    public static T Load<T>(string fileName = "settings.json") where T : new()
    {
        var filePath = GetFilePath(fileName);

        try
        {
            if (File.Exists(filePath))
            {
                var json = File.ReadAllText(filePath, Encoding.UTF8);
                return JsonSerializer.Deserialize<T>(json, _jsonOptions) ?? new T();
            }
        }
        catch (JsonException ex)
        {
            // 处理 JSON 格式错误
            Debug.WriteLine($"JSON 解析错误: {ex.Message}");
            // 尝试部分恢复
            return PartialRecovery<T>(filePath, ex);
        }
        catch (Exception ex)
        {
            // 在实际应用中应使用日志框架
            Debug.WriteLine($"加载设置失败: {ex.Message}");
        }

        return new T();
    }

    // 部分恢复策略
    private static T PartialRecovery<T>(string filePath, JsonException ex) where T : new()
    {
        try
        {
            // 1. 创建默认实例
            var defaultSettings = new T();

            // 2. 尝试合并有效设置
            var json = File.ReadAllText(filePath);
            var invalidSettings = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
            if (invalidSettings != null)
            // 3. 使用反射应用有效值
            { 
                var properties = typeof(T).GetProperties();
                foreach (var prop in properties)
                {
                    if (invalidSettings.TryGetValue(prop.Name, out var element))
                    {
                        try
                        {
                            var value = JsonSerializer.Deserialize(
                                element.GetRawText(),
                                prop.PropertyType
                            );
                            prop.SetValue(defaultSettings, value);
                        }
                        catch
                        {
                            // 忽略无法解析的值
                        }
                    }
                }
            }
            return defaultSettings;
        }
        catch
        {
            return new T(); // 回退到完全默认
        }
    }

    public static async Task SaveAsync<T>(T settings, string fileName = "settings.json")
    {
        var filePath = GetFilePath(fileName);

        try
        {
            var directory = Path.GetDirectoryName(filePath);

            // 添加空值检查 - 修复警告1
            if (string.IsNullOrWhiteSpace(directory))
            {
                throw new InvalidOperationException($"无法从路径 '{filePath}' 获取有效的目录名");
            }

            // 确保目录存在
            Directory.CreateDirectory(directory); // 现在 directory 不可能为 null

            await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
            await JsonSerializer.SerializeAsync(fileStream, settings, _jsonOptions);
            await fileStream.FlushAsync();

            Debug.WriteLine($"设置已保存到: {filePath}");
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"保存设置失败: {ex.Message}");

            // 确保在UI线程显示消息
            Application.Current?.Dispatcher?.Invoke(() =>
            {
                MessageBox.Show(
                    "保存设置失败",
                    "设置问题",
                    MessageBoxButton.OK,
                    MessageBoxImage.Warning);
            });
        }
    }

    public static void Save<T>(T settings, string fileName = "settings.json")
    {
        var filePath = GetFilePath(fileName);

        try
        {
            var directory = Path.GetDirectoryName(filePath);
            if (!string.IsNullOrWhiteSpace(directory))
            {
                Directory.CreateDirectory(directory);
            }

            var json = JsonSerializer.Serialize(settings, _jsonOptions);
            File.WriteAllText(filePath, json, Encoding.UTF8);

            Debug.WriteLine($"设置已保存到: {filePath}");
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"保存设置失败: {ex.Message}");
        }
    }

    public static string GetFilePath(string fileName)
    {
        // 确保文件名有效
        if (string.IsNullOrWhiteSpace(fileName))
        {
            fileName = "bak.json";
        }

#if DEBUG
        // 获取当前程序运行目录
        string appDir = AppDomain.CurrentDomain.BaseDirectory;
        return Path.Combine(appDir, "Config", fileName);
#else
        // 路径为 C:\Users\[用户名]\AppData\Roaming\
        string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        return Path.Combine(
            appDataPath,
            "Fairy",
            "StudentInfoSystem",
            "Config",
            fileName);
#endif
    }
}